﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data.Linq;
using System.Globalization;
using System.Windows.Input;

namespace Chefbook.UserActions
{
    /// <summary>
    /// Abstract base class for user actions
    /// </summary>
    public abstract class UserActionBase : IUserAction, ICommand
    {
        /// <summary>
        /// By default an action is undoable
        /// </summary>
        protected UserActionBase()
        {
            IsUndoable = true;
        }

        /// <summary>
        /// Gets or sets whether an action was done.
        /// <remarks>An action can only be undone if it was done previously</remarks>
        /// </summary>
        protected bool WasDone { get; set; }

        /// <summary>
        /// Gets or sets whether an action is undoable
        /// </summary>
        public bool IsUndoable { get; protected set; }

        /// <summary>
        /// Makes sure an action wasn't already done.  Cannot do an action twice.  Create a new action instead.
        /// </summary>
        public virtual void DoAction()
        {
            if (WasDone)
                throw new InvalidOperationException(string.Format(CultureInfo.InvariantCulture, "Cannot redo action that wasn't undone: (0)", this));
            WasDone = true;
        }

        /// <summary>
        /// Reverts an action taken.  Can only undo an action that was done
        /// </summary>
        public virtual void UndoAction()
        {
            if (!WasDone)
                throw new InvalidOperationException(string.Format(CultureInfo.InvariantCulture, "Cannot undo action that wasn't done: (0)", this));
            WasDone = false;
        }

        #region ICommand Members

        bool ICommand.CanExecute(object parameter)
        {
            return true;
        }

        event EventHandler ICommand.CanExecuteChanged
        {
            add { CommandManager.RequerySuggested += value; }
            remove { CommandManager.RequerySuggested -= value; }
        }

        void ICommand.Execute(object parameter)
        {
            DoAction();
        }

        #endregion
    }
}
